import {
  autorun,
  reaction,
  intercept,
  extendObservable,
  computed
} from 'mobx';

/* 147 */
// 子对象都需要用registerProperty种族测，同时如果是原生对象，需要传递第三个参数，即默认值。
export function registerProperty(sobject, propertyName, defaultOptions) {
  return intercept(sobject, propertyName, function(changed) {
    if (changed.type === 'update') {
      // if (changed.newValue && changed.object.value !== changed.newValue) {
      if (typeof changed.newValue !== 'undefined' && changed.object.value !== changed.newValue) {
        var jsonObject = changed.newValue && changed.newValue.toJSON && changed.newValue.toJSON() || changed
          .newValue;
        if (sobject[propertyName].xbsjFromJSON) {
          sobject[propertyName].xbsjFromJSON(jsonObject);
        } else {
          var newJsonObject = (0, _assign2.default)({}, defaultOptions, jsonObject);
          var sop = sobject[propertyName];
          (0, _keys2.default)(newJsonObject).forEach(function(key) {
            // sop[key]会导致值为undefined的属性无法赋值！
            // sop[key] && (sop[key] = newJsonObject[key]);
            key in sop && (sop[key] = newJsonObject[key]);
          });
        }
      }
    }

    return null;
  });
}

export function _registerArrayProperty(sobject, propertyName) {
  var disposers = [];
  disposers.push(intercept(sobject, propertyName, function(changed) {
    if (changed.type === 'update') {
      if (changed.newValue && Array.isArray(changed.newValue)) {
        if (changed.object.value !== changed.newValue) {
          var _sobject$propertyName;

          (_sobject$propertyName = sobject[propertyName]).splice.apply(_sobject$propertyName, [0, sobject[
            propertyName].length].concat((0, _toConsumableArray3.default)(changed.newValue)));
        }
      }
    }
    return null;
  }));

  disposers.push(intercept(sobject[propertyName], function(changed) {
    if (changed.type === 'splice') {
      // 元素个数必须始终为3！
      if (changed.removedCount !== changed.added.length) {
        console.warn('❌ 数组赋值有误！');
        return null;
      }
    }

    return changed;
  }));

  return function() {
    disposers.forEach(function(d) {
      return d();
    });
    disposers.length = 0;
  };
}

export function registerPosition(sobject) {
  var propertyName = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'position';

  return _registerArrayProperty(sobject, propertyName);
}

export function registerRotation(sobject) {
  var propertyName = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'rotation';

  return _registerArrayProperty(sobject, propertyName);
}

export function registerArrayProperty(sobject, propertyName, createFunc, destoryFunc) {
  var disposers = [];
  disposers.push(intercept(sobject, propertyName, function(changed) {
    if (changed.type === 'update') {
      if (changed.newValue && Array.isArray(changed.newValue)) {
        if (changed.object.value !== changed.newValue) {
          var _sobject$propertyName2;

          (_sobject$propertyName2 = sobject[propertyName]).splice.apply(_sobject$propertyName2, [0,
            sobject[propertyName].length
          ].concat((0, _toConsumableArray3.default)(changed.newValue)));
        }
      }
    }
    return null;
  }));

  disposers.push((0, _interceptArray2.default)(sobject[propertyName], function(elementJson) {
    // elementJson = elementJson && elementJson.toJSON && elementJson.toJSON() || elementJson;
    var element = createFunc(elementJson);
    // xbsjFromJSON赋值position会一个一个赋值，导致fromPosition时有数值为undefined。所以加一个runInAction避免频繁响应。
    // element.xbsjFromJSON(elementJson);
    return element;
  }, function(element) {
    destoryFunc(element);
  }));

  return function() {
    disposers.forEach(function(d) {
      return d();
    });
    disposers.length = 0;
  };
}
